package glemipsc.instructions;

import glemipsc.Address;
import glemipsc.ErrorLevel;
import glemipsc.Function;
import glemipsc.GLEMipsC;
import glemipsc.Type;
import glemipsc.implementations.Argument;

import java.io.Serializable;
import java.util.List;

public class CycleControl extends BaseInstruction implements Serializable, Instruction, Expression {
	private String instruction;
	private Address addr;
	private Function func;

	public CycleControl(String instruction) {
		this.instruction = instruction;
	}
	
	public Expression getOperand(int index) {
		return null;
	}
	
	public int getNumberOfOperands() {
		return 0;
	}

	public int getSize() {
		return 0;
	}

	public Type getType() {
		return Type.createFromName("void");
	}

	public int getImmediateValue() {
		return 0;
	}

	public boolean isImmediate() {
		return false;
	}

	public Address getStoreAddress() {
		return addr;
	}

	public int getStoredSize() {
		// TODO Auto-generated method stub
		return 0;
	}

	public boolean isStored() {
		return true;
	}

	public void setStoreAddress(Address addr) {
		this.addr = addr;
	}

	public void computeInstruction(Argument result, List<glemipsc.implementations.Instruction> instructions, Function func) {
		glemipsc.implementations.Implementation impl = GLEMipsC.compiler.getEnvironment().implementation;
		Instruction parent = this;
		Address gotoAddress = null;
		
		while (true) {
			if (parent == null)
				break;
			if (parent.getClass().getCanonicalName().equals("glemipsc.instructions.For"))
				break;
			if (parent.getClass().getCanonicalName().equals("glemipsc.instructions.While"))
				break;
			if (parent.getClass().getCanonicalName().equals("glemipsc.instructions.Switch"))
				break;
			parent = parent.getParent();
		}
		
		if (parent == null) {
			GLEMipsC.compiler.displayError(ErrorLevel.ERROR, "Unable to find a suitable parent for " + instruction + " instruction");
			return;
		}
		
		if (instruction.equals("break")) {
			if (parent.getClass().getCanonicalName().equals("glemipsc.instructions.For"))
				gotoAddress = ((For) parent).getBreakAddress();
			else if (parent.getClass().getCanonicalName().equals("glemipsc.instructions.While"))
				gotoAddress = ((While) parent).getBreakAddress();
			else if (parent.getClass().getCanonicalName().equals("glemipsc.instructions.Switch"))
				gotoAddress = ((Switch) parent).getBreakAddress();
		}
		else if (instruction.equals("continue")) {
			if (parent.getClass().getCanonicalName().equals("glemipsc.instructions.For"))
				gotoAddress = ((For) parent).getContinueAddress();
			else if (parent.getClass().getCanonicalName().equals("glemipsc.instructions.While"))
				gotoAddress = ((While) parent).getContinueAddress();
		}
		
		if (gotoAddress == null)
			return;
		
		instructions.add(impl.getJmp(gotoAddress));
	}

}
